﻿using System.Diagnostics;
using System.IO;
using System;

namespace USU.MetricsMonitor.Common
{
    public class ConsoleApplicationException : Exception
    {
        public ConsoleApplicationException(string msg) : base(msg) { }
        public ConsoleApplicationException(string msg, Exception inner) : base(msg, inner) { }
    }
    public class ConsoleApplication : IDisposable
    {
        private Process process;
        private string error = "";

        public ConsoleApplication(string fileName, string arguments)
        {
            process = new Process();

            process.StartInfo = new ProcessStartInfo(fileName, arguments)
            {
                CreateNoWindow = true,
                UseShellExecute = false,
                RedirectStandardError = true,
                RedirectStandardOutput = true
            };
            process.ErrorDataReceived += (obj, earg) => { error += earg.Data; };
            try
            {
                process.Start();
            }
            catch (Exception e)
            {
                throw new ConsoleApplicationException(
                    String.Format("не удалось запустить '{0}'", process.ProcessName), e
                );
            }
            process.BeginErrorReadLine();
        }

        public void RedirectOutputTo(Stream stream)
        {
            process.OutputDataReceived += (obj, earg) =>
            {
                if (earg.Data != null)
                {
                    byte[] buffer = Console.OutputEncoding.GetBytes(earg.Data);
                    stream.Write(buffer, 0, buffer.Length);
                }
            };
            process.BeginOutputReadLine();
        }

        public void WaitForExit()
        {
            process.WaitForExit();
        }

        public Stream OutputStream
        {
            get { return process.StandardOutput.BaseStream; }
        }

        public void Close()
        {
            process.Close();
            if (error.Length > 0)
                throw new ConsoleApplicationException(error);
        }

        public void Dispose()
        {
            Close();
            process.Dispose();
        }
    }
}
